package grpc

import (
	"context"
	"examination/rpc/models/dao"
	"examination/rpc/models/services"
	"examination/rpc/pkg"
	user1 "examination/rpc/proto/user"
	"github.com/dgrijalva/jwt-go"
	"time"
)

type UserServer struct {
	user1.UnimplementedRegisterServerServer
}

func (s *UserServer) Register(ctx context.Context, req *user1.RegisterReq) (*user1.RegisterResp, error) {
	user := dao.User{
		Name: req.Name,
		Pass: req.Pass,
	}
	err := services.CreateUser(user)
	if err != nil {
		return &user1.RegisterResp{
			Code: 400,
			Msg:  "创建失败",
		}, err
	}
	resp := &user1.RegisterResp{
		Code: 200,
		Msg:  "创建用户成功",
	}
	return resp, err
}

func (s *UserServer) AddTestQuestions(ctx context.Context, req *user1.AddTestQuestionsReq) (*user1.AddTestQuestionsResp, error) {
	test := dao.TestQuestions{
		TestQuestionType: int(req.TestQuestionType),
		Difficulty:       int(req.Difficulty),
		LevelOnce:        req.LevelOnce,
		LevelTwo:         req.LevelTwo,
		Author:           req.Author,
		AuthorId:         req.AuthorId,
		Create:           req.Create,
		CreateId:         req.CreateId,
		Reviewer:         req.Reviewer,
		ReviewerId:       req.ReviewerId,
		Topic:            req.Topic,
		A:                req.A,
		B:                req.B,
		C:                req.C,
		D:                req.D,
		Answer:           req.Answer,
		Analysis:         req.Analysis,
		Keywords:         req.Keywords,
	}
	err := services.CreateTestQuestions(test)
	if err != nil {
		return &user1.AddTestQuestionsResp{
			Code: 400,
			Msg:  "创建失败",
		}, err
	}
	resp := &user1.AddTestQuestionsResp{
		Code: 200,
		Msg:  "创建成功",
	}
	return resp, err
}

func (s *UserServer) QueryTestQuestions(ctx context.Context, req *user1.QueryTestQuestionsReq) (*user1.QueryTestQuestionsResp, error) {
	topic, err := services.QueryTestQuestionsByTopic(req.Topic)
	if err != nil {
		return &user1.QueryTestQuestionsResp{
			Code: 400,
			Msg:  "列表展示事变",
			Data: nil,
		}, err
	}
	var TestQuestions []*user1.TestQuestionsInfo
	for _, v := range topic {
		TestQuestions = append(TestQuestions, &user1.TestQuestionsInfo{
			TestQuestionType: int64(v.TestQuestionType),
			Difficulty:       int64(v.Difficulty),
			LevelOnce:        v.LevelOnce,
			LevelTwo:         v.LevelTwo,
			Author:           v.Author,
			AuthorId:         v.AuthorId,
			Create:           v.Create,
			CreateId:         v.CreateId,
			Reviewer:         v.Reviewer,
			ReviewerId:       v.ReviewerId,
			Topic:            v.Topic,
			A:                v.A,
			B:                v.B,
			C:                v.C,
			D:                v.D,
			Answer:           v.Answer,
			Analysis:         v.Analysis,
			Keywords:         v.Keywords,
		})
	}
	resp := &user1.QueryTestQuestionsResp{
		Code: 200,
		Msg:  "查询成功",
		Data: TestQuestions,
	}
	return resp, err
}

func (s *UserServer) UpdateTestQuestions(ctx context.Context, req *user1.UpdateTestQuestionsReq) (*user1.UpdateTestQuestionsResp, error) {
	err := services.UpdateAnswer(req.Topic, req.Answer)
	if err != nil {
		return &user1.UpdateTestQuestionsResp{
			Code: 400,
			Msg:  "修改失败",
		}, err
	}
	resp := &user1.UpdateTestQuestionsResp{
		Code: 200,
		Msg:  "修改成功",
	}
	return resp, err
}

func (s *UserServer) DeletedTestQuestions(ctx context.Context, req *user1.DeletedTestQuestionsReq) (*user1.DeletedTestQuestionsResp, error) {
	err := services.DeleteTestQuestionsByTopic(req.Topic)
	if err != nil {
		return &user1.DeletedTestQuestionsResp{
			Code: 400,
			Msg:  "删除失败",
		}, err
	}
	resp := &user1.DeletedTestQuestionsResp{
		Code: 200,
		Msg:  "删除成功",
	}
	return resp, err
}

func (s *UserServer) AddTestPaper(ctx context.Context, req *user1.AddTestPaperReq) (*user1.AddTestPaperResp, error) {
	TestPaper := dao.TestPaper{
		ComposingType:        int(req.ComposingType),
		TestPaperName:        req.TestPaperName,
		TestPaperType:        int(req.TestPaperType),
		ExamDuration:         req.ExamDuration,
		SortingQuestionsType: int(req.SortingQuestionsType),
		SelectionSort:        int(req.SelectionSort),
		TotalScore:           int(req.TotalScore),
		PassScore:            int(req.PassScore),
		Reviewer:             req.Reviewer,
		ExamNotice:           req.ExamNotice,
	}
	err := services.CreateTestPaper(TestPaper)
	if err != nil {
		return &user1.AddTestPaperResp{
			Code: 400,
			Msg:  "创建失败",
		}, err
	}
	resp := &user1.AddTestPaperResp{
		Code: 200,
		Msg:  "创建创建试卷成功",
	}
	return resp, err
}

func (s *UserServer) QueryTestPaper(ctx context.Context, req *user1.QueryTestPaperReq) (*user1.QueryTestPaperResp, error) {
	composingType, err := services.QueryTestPaperByComposingType(req.TestPaperName)
	if err != nil {
		return &user1.QueryTestPaperResp{
			Code: 400,
			Msg:  "查询失败",
			Data: nil,
		}, err
	}

	var TestPaperList []*user1.TestPaperInfo

	for _, v := range composingType {
		TestPaperList = append(TestPaperList, &user1.TestPaperInfo{
			ComposingType:        int64(v.ComposingType),
			TestPaperName:        v.TestPaperName,
			TestPaperType:        int64(v.TestPaperType),
			ExamDuration:         v.ExamDuration,
			SortingQuestionsType: int64(v.SortingQuestionsType),
			SelectionSort:        int64(v.SelectionSort),
			TotalScore:           int64(v.TotalScore),
			PassScore:            int64(v.PassScore),
			Reviewer:             v.Reviewer,
			ExamNotice:           v.ExamNotice,
		})
	}
	resp := &user1.QueryTestPaperResp{
		Code: 200,
		Msg:  "查询成功",
		Data: TestPaperList,
	}
	return resp, err
}

func (s *UserServer) TestPaperList(ctx context.Context, req *user1.TestPaperListReq) (*user1.TestPaperListResp, error) {
	composingType, err := services.TestPaperListByComposingType(int(req.ComposingType), int(req.Page), int(req.PageSize))
	if err != nil {
		return &user1.TestPaperListResp{
			Code: 400,
			Msg:  "列表展示失败",
			Data: nil,
		}, err
	}

	var testPaperList []*user1.TestPaperInfo

	for _, v := range composingType {
		testPaperList = append(testPaperList, &user1.TestPaperInfo{
			ComposingType:        int64(v.ComposingType),
			TestPaperName:        v.TestPaperName,
			TestPaperType:        int64(v.TestPaperType),
			ExamDuration:         v.ExamDuration,
			SortingQuestionsType: int64(v.SortingQuestionsType),
			SelectionSort:        int64(v.SelectionSort),
			TotalScore:           int64(v.TotalScore),
			PassScore:            int64(v.PassScore),
			Reviewer:             v.Reviewer,
			ExamNotice:           v.ExamNotice,
		})
	}
	resp := &user1.TestPaperListResp{
		Code: 200,
		Msg:  "列表展示成功",
		Data: testPaperList,
	}
	return resp, err
}

func (s *UserServer) AddExamDetails(ctx context.Context, req *user1.AddExamDetailsReq) (*user1.AddExamDetailsResp, error) {
	exam := dao.ExamDetails{
		Name:         req.Name,
		Score:        int(req.Score),
		CorrectTopic: int(req.CorrectTopic),
		ErrorTopic:   int(req.ErrorTopic),
	}
	err := services.CreateExamDetails(exam)
	if err != nil {
		return &user1.AddExamDetailsResp{
			Code: 400,
			Msg:  "创建失败",
		}, err
	}
	resp := &user1.AddExamDetailsResp{
		Code: 200,
		Msg:  "创建成功",
	}
	return resp, err
}

func (s *UserServer) QueryExamDetails(ctx context.Context, req *user1.QueryExamDetailsReq) (*user1.QueryExamDetailsResp, error) {
	list, err := services.QueryExamDetailsByName(req.Name)
	if err != nil {
		return &user1.QueryExamDetailsResp{
			Code: 400,
			Msg:  "查询失败",
			Data: nil,
		}, err
	}
	var examDetailsList []*user1.ExamDetailsInfo
	for _, v := range list {
		examDetailsList = append(examDetailsList, &user1.ExamDetailsInfo{
			Name:         v.Name,
			Score:        int64(v.Score),
			CorrectTopic: int64(v.CorrectTopic),
			ErrorTopic:   int64(v.ErrorTopic),
		})
	}
	resp := &user1.QueryExamDetailsResp{
		Code: 200,
		Msg:  "详情展示成功",
		Data: examDetailsList,
	}
	return resp, err
}

func (s *UserServer) Login(ctx context.Context, req *user1.LoginReq) (*user1.LoginResp, error) {
	res, err := services.GetUserInfo(req.Name)
	if err != nil {
		return &user1.LoginResp{
			Code: 400,
			Msg:  "用户不存在",
		}, err
	}
	CustomClaims := pkg.CustomClaims{
		ID: res.ID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Unix() + 86400,
		},
	}
	token, err := pkg.NewJWT("2211A").CreateToken(CustomClaims)
	if err != nil {
		return &user1.LoginResp{
			Code: 400,
			Msg:  "登录失败",
		}, err
	}
	resp := &user1.LoginResp{
		Code: 200,
		Msg:  "登录成功",
		Data: token,
	}
	return resp, err
}

func (s *UserServer) AddExamStatus(ctx context.Context, req *user1.AddExamStatusReq) (*user1.AddExamStatusResp, error) {
	ExamStatus := dao.ExamStatus{
		ExamId: int(req.ExamId),
		Status: int(req.Status),
	}
	err := services.CreateExamStatus(ExamStatus)
	if err != nil {
		return &user1.AddExamStatusResp{
			Code: 400,
			Msg:  "创建失败",
		}, err
	}
	resp := &user1.AddExamStatusResp{
		Code: 200,
		Msg:  "阅卷成功",
	}
	return resp, err
}
